using Headspring.Training.Core.Model;
using Headspring.Training.Core.Model.StateCommands;
using Headspring.Training.Core.Services;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace Headspring.Training.UnitTests.Model.StateCommands
{
	[TestFixture]
	public class DraftToCancelledCommandTester : StateCommandBaseTester
	{
		protected override StateCommandBase GetStateCommand(WorkOrder order,
		                                                    Employee employee)
		{
			return new DraftToCancelledCommand(order, employee);
		}

		[Test]
		public void ShouldBeValid()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Draft};
			var employee = new Employee();
			order.Creator = employee;

			var command = new DraftToCancelledCommand(order, employee);
			Assert.That(command.IsValid(), Is.True);
		}

		[Test]
		public void ShouldNotBeValidInWrongStatus()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Cancelled};
			var employee = new Employee();
			order.Creator = employee;

			var command = new DraftToCancelledCommand(order, employee);
			Assert.That(command.IsValid(), Is.False);
		}

		[Test]
		public void ShouldNotBeValidWithWrongEmployee()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Draft};
			var employee = new Employee();
			order.Creator = employee;

			var command = new DraftToCancelledCommand(order, new Employee());
			Assert.That(command.IsValid(), Is.False);
		}

		[Test]
		public void ShouldShowCorrectVerb()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Cancelled};
			var command = new DraftToCancelledCommand(order, new Employee());

			Assert.AreEqual("Cancel", command.TransitionVerbPresentTense);
			Assert.AreEqual("Cancelled", command.TransitionVerbPastTense);
		}

		[Test]
		public void ShouldTransitionStateProperly()
		{
			var order = new WorkOrder {Number = "123", Status = WorkOrderStatus.Draft};
			var employee = new Employee();
			order.Creator = employee;

			var commandVisitor = MockRepository.GenerateMock<IStateCommandVisitor>();
			commandVisitor.Expect(visitor => visitor.SaveWorkOrder(order));
			commandVisitor.Expect(
				visitor => visitor.SendMessage("You have cancelled work order 123"));
			commandVisitor.Expect(visitor => visitor.EditWorkOrder(order));

			var command = new DraftToCancelledCommand(order, employee);
			command.Execute(commandVisitor);

			commandVisitor.VerifyAllExpectations();
			Assert.That(order.Status, Is.EqualTo(WorkOrderStatus.Cancelled));
		}
	}
}